﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SW2A311A
{

    #region Enums
    public enum EHoodType { Frithængt, Væghængt, Indbygget }
    #endregion

    public class Hood : Product, ISmileyRating
    {
        #region Instansvariabler
        public bool WithFilter { get; private set; }
        public double SuctionCapacity
        {
            get { return _suctionCapacity; }
            private set
            {
                if (value > 0)
                    _suctionCapacity = value;
                else
                    throw new ArgumentNullException("Suctioncapacity", "Skal være positivt tal");
            }
        }
        private double _suctionCapacity;

        public readonly int MaxKitchenSize; //Større udregning flyttet ned i "Initializer-metode"
        public ESmiley Smiley { get; private set; }
        public EHoodType HoodType { get; private set; }

        public double NoiseLevel //Skal stemme overens til krav til lydniveau sat i NoiseLevelCalc klassen
        {
            get { return _noiseLevel; }
            private set { _noiseLevel = NoiseLevelCalc.Set(value); }
        }
        private double _noiseLevel;
        #endregion

        #region Constructors
        public Hood(string name, double price, EHoodType hoodType, double suctionCapacity, double noiseLevel, bool withFilter)
            : base(name, price)
        {
            HoodType = hoodType;
            SuctionCapacity = suctionCapacity;
            NoiseLevel = noiseLevel;
            WithFilter = withFilter;
            Init(out MaxKitchenSize);
            Smiley = GetSmiley();
        }
        #endregion

        #region Metoder
        public ESmiley GetSmiley()
        {
            if (WithFilter)
                return ESmiley.Neutral;
            else
                return ESmiley.Negative;
        }

        private void Init(out int maxKitchenSize)
        {
            maxKitchenSize = 0;
            if (SuctionCapacity >= 0)    //Kræver SuctionCapacity 
            {
                if (new Range(875, int.MaxValue).IsBetweenOrEqualMin(SuctionCapacity))
                    maxKitchenSize = 35;
                else if (new Range(750, 1100).IsBetweenOrEqualMin(SuctionCapacity))
                    maxKitchenSize = 30;
                else if (new Range(625, 900).IsBetweenOrEqualMin(SuctionCapacity))
                    maxKitchenSize = 25;
                else if (new Range(500, 750).IsBetweenOrEqualMin(SuctionCapacity))
                    maxKitchenSize = 20;
                else if (new Range(375, 750).IsBetweenOrEqualMin(SuctionCapacity))
                    maxKitchenSize = 15;
                else if (new Range(0, 500).IsBetweenOrEqualMin(SuctionCapacity))
                    maxKitchenSize = 10;
                else throw new ArgumentOutOfRangeException("SuctionCapacity", "Er udenfor tilladt rækkevidde");
            }
        }

        public override string ToString()
        {
            return String.Format
                ("Type: Hood\nManufacturer: {0}\nType: {1}\nFilter: {2}\nSuctioncapacity: {3}m3/t\nNoiselevel: {4}dB\n" +
                "Maximum Recommended Kitchensize: {5}m^2\nSmiley: {6}\nPrice: {7:C}\n",
                Name, HoodType, WithFilter ? "Yes" : "No", SuctionCapacity,
                NoiseLevel, MaxKitchenSize, Smiley, Price);
        }

        #region Equals Metoder

        public override bool Equals(object obj)
        // Override af Equals metoden. Den tester om objektet metoden kaldes på er værdi-mæssigt ens med indput parameter objektet.
        // Sammenligning med et object (hvis typen ikke kendes).
        {
            Hood p = obj as Hood;

            if (this.GetType() != obj.GetType())
                return false;

            return base.Equals(obj) &&
                WithFilter == p.WithFilter &&
                HoodType == p.HoodType &&
                SuctionCapacity == p.SuctionCapacity &&
                MaxKitchenSize == p.MaxKitchenSize &&
                Smiley == p.Smiley &&
                NoiseLevel == p.NoiseLevel;
        }

        // Sammenligning med en anden Product hvor typen kendes.
        public bool Equals(Hood p)
        {
            return base.Equals((Product)p) &&
                WithFilter == p.WithFilter &&
                HoodType == p.HoodType &&
                SuctionCapacity == p.SuctionCapacity &&
                MaxKitchenSize == p.MaxKitchenSize &&
                Smiley == p.Smiley &&
                NoiseLevel == p.NoiseLevel;
        }

        // GetHashCode skal overrides sammen med Equals. Vi generer en seudo-telfældig hash kode.
        public override int GetHashCode()
        {
            return base.GetHashCode() ^
                WithFilter.GetHashCode() ^
                HoodType.GetHashCode() ^
                SuctionCapacity.GetHashCode() ^
                MaxKitchenSize.GetHashCode() ^
                Smiley.GetHashCode() ^
                NoiseLevel.GetHashCode();
        }
        #endregion
        #endregion
    }
}
